<?php

namespace common\service;

use common\exception\LogicException;
use common\model\StatusModel;
use common\model\EntityModel;
use common\model\TaskModel;
use common\model\TaskWorkOrderModel;
use common\validate\Module;
use support\ErrorCode;
use think\Exception;

class SeqAbolitionService
{

    public $taskAbolitionService;

    public function __construct()
    {
        $this->taskAbolitionService = new TaskAbolitionService();
    }


    /**
     * 处理废除任务
     * @param $param
     * @return bool
     * @throws Exception
     */
    public function execAbo($param)
    {
        // 获取序列清单列表
        $entityList = $this->getEntityData($param);
        if (empty($entityList)) {
            throw new LogicException('shot seq data is null', ErrorCode::SHOT_SEQ_DATA_IS_NULL);
        }
        // 获取任务状态
        $entityId = array_unique(array_column($entityList, 'eid'));

        $taskStatus = $this->taskAbolitionService->getTaskStatus($param['project_id'], $entityId, $taskList);

        // 任务开始制作,无法操作序列废除
        if ($taskStatus) {
            throw new LogicException('seq task is start unable abolish', ErrorCode::SEQ_TASK_IS_START_UNABLE_ABOLISH);
        } else {
            // 判断任务是否外包
            $this->isOutsourcing($taskList);
            $this->removeTask($taskList);
            // 移除镜头与序列关联关系
            $this->removeShotSeqRelation($entityList);
            // 解除工单会话群
            $this->taskAbolitionService->batchDisbandChat($taskList);
        }
        return true;
    }


    /**
     * 移除镜头关联序列
     * @param $entityList
     * @return void
     */
    public function removeShotSeqRelation($entityList)
    {
        if (empty(array_column($entityList, 'eid'))) {
            throw new LogicException('init shot data is null', ErrorCode::GET_INIT_SHOT_DATA_FAIL);
        }
        // 删除序列,镜头
        $delSeqId = array_unique(array_column($entityList, 'eid'));
        model(EntityModel::class)->where(['id' => ['IN', $delSeqId]])->delete();
    }


    /**
     * 获取序列清单
     * @param $param
     * @return array|false|mixed|string
     * @throws Exception
     */
    public function getEntityData($param)
    {

        $field = 'entity.id,entity.name,entity.code,entity.json,entity.entity_id,task.tenant_id,';
        $field .= 'task.executor_tenant_id,task.json,task.id as tid,entity.id as eid';
        $seqConditions['module_id'] = module_by_code('storyboard')['id'];
        $seqConditions['project_id'] = $param['project_id'];
        $seqConditions["json->>'$.storyboard_sequence'"] = $param['storyboard_sequence'];
        $seqConditions["initial_episode_code"] = $param['initial_episode_code'];

        $seqId = model(EntityModel::class)->where($seqConditions)->field('id')->select();
        if (empty($seqId)) {
            return [];
        }
        $where['entity.project_id'] = $param['project_id'];
        $where["entity.json->>'$.shot_storyboard'"] = ['IN', array_column($seqId, 'id')];

        $orWhere['entity.project_id'] = $param['project_id'];
        $orWhere['entity.id'] = ['IN', array_column($seqId, 'id')];

        $orWhereB['entity.code'] = $param['storyboard_sequence'];
        $orWhereB['entity.initial_episode_code'] = $param['initial_episode_code'];
        $orWhereB['entity.project_id'] = $param['project_id'];

        $newFilter['_complex'][] = [
            $where, $orWhere, $orWhereB,
            '_logic' => 'or',
        ];

        return model(EntityModel::class)->join('task ON task.entity_id = entity.id')->field($field)->where($newFilter)->select();
    }


    /**
     * 判断是否外包订单
     * @param $taskList
     * @return false
     */
    public function isOutsourcing($taskList)
    {
        if (!empty($taskList)) {
            foreach ($taskList as $val) {
                if (!empty($val['executor_tenant_id'])) {
                    if ($val['executor_tenant_id'] != $val['tenant_id']) {
                        throw new LogicException("Include outsourcing orders", ErrorCode::TASK_ABO_OUTSOURCING_ORDERS);
                    }
                }
            }
        }
        return false;
    }


    /**
     * 删除任务
     * @param $taskList
     * @return false|float|int|mixed|string
     */
    public function removeTask($taskList)
    {
        if (empty($taskList)) {
            throw new LogicException('delete shot task status fail', ErrorCode::UPDATE_SHOT_TASK_ABO_STATUS_FAIL);
        }
        $deleteId = array_column($taskList, 'id');
        return model(TaskModel::class)->where(['id' => ['IN', $deleteId]])->delete();
    }
}